package com.dzsw.zk.demo;

import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.data.Stat;

import java.util.List;

public class CuratorDemo {

    private CuratorFramework curator;

    public CuratorDemo(String ipAndPort, int timeout) {
        //重试策略，初试时间1秒，重试10次
        RetryPolicy policy = new ExponentialBackoffRetry(1000, 10);
        //通过工厂创建Curator
        curator = CuratorFrameworkFactory.builder()
                .connectString(ipAndPort)
                .sessionTimeoutMs(timeout)
                .retryPolicy(policy)
                .build();
        //开启连接
        curator.start();
    }

    /**
     * @param path
     * @param value
     * @return 1=正常创建 2=节点已存在 3=其他异常无法创建
     */
    public int createNode(String path, String value, CreateMode createMode) {
        int result = 3;
        try {
            curator.create().creatingParentsIfNeeded()
                    .withMode(createMode)
                    .forPath(path, value.getBytes());
            result = 1;
        } catch (Exception e) {
            if (e instanceof KeeperException.NodeExistsException) {
                result = 2;
            }
        }
        return result;
    }

    public int getSeq() throws Exception {
        // 1.用当前日期yyyyMMdd获取node
        String key = "/seq/20200909";
        Stat stat = curator.checkExists().forPath(key);
        if (stat == null) {
            try {
                createNode(key, "1", CreateMode.PERSISTENT);
                return 1;
            } catch (Exception e) {
                if (e instanceof KeeperException.NoNodeException) {

                }
            }
        }
        byte[] bs = curator.getData().forPath(key);
//        Integer i = bs.
//        curator.transactionOp()
//            byte[] bytes = curator.getData().forPath(key);
        System.out.println(stat);
        return 1;
        // 1-1.没有创建并写入1，写入成功返回

        // 2.写入不成功，读node值并加1，用CAS，成功返回值


    }

    public int computeDataCenterAndWorkId() throws Exception {
        int childPath = -1;
        int result;
        do {
            List<String> nodePathList = curator.getChildren().forPath("/wns");
            nodePathList.sort((o1, o2) -> Integer.parseInt(o1) - Integer.valueOf(o2));
            int i = 0;
            boolean findBreak = false;
            for (String nodePath : nodePathList) {
                if (Integer.parseInt(nodePath) > i) {
                    findBreak = true;
                    break;
                }
                i++;
            }
            childPath = findBreak ? i : i + 1;
            if (childPath > 1023) {
                throw new Exception("Zookeeper节点已满");
            }
            result = createNode("/wns/" + childPath, "192.168.85.101", CreateMode.EPHEMERAL);
        } while (result == 2);
        return childPath;
    }

    public static void main(String[] args) throws Exception {
//        ExecutorService executors = Executors.newFixedThreadPool(20);
        String ipAndPort = "127.0.0.1:2181";
        int timeout = 4000;
        CuratorDemo cd = new CuratorDemo(ipAndPort, timeout);
//        cd.createNode("/wns", "12345", CreateMode.PERSISTENT);
//        for (int i = 0; i < 30; i++) {
//            executors.execute(new Runnable() {
//                @Override
//                public void run() {
//                    int path = 0;
//                    try {
//                        path = cd.computeDataCenterAndWorkId();
//                        System.out.println(String.format("NUM=[%s], DC=[%s], WK=[%s]", path, path >> 5, path & 0x1F));
//                    } catch (Exception e) {
//                        e.printStackTrace();
//                    }
//                }
//            });
//        }

//        cd.getSeq();
//        Thread.sleep(60 * 1000);
        System.out.println(cd.go(9544484484L, 4));
    }

    public long go(long num, int giveUpNum) {
        long result = num;
        long tmp = num;
        int i = 0;
        do {
            if ((tmp % 10) == giveUpNum) {
                result = result + (long)Math.pow(10, i);
            }
            tmp = tmp / 10;
            i++;
        } while(tmp > 0); // 当tmp小于等于0退出
        return result;
    }
}
